<template>
  <div class="tree">
    <ul>
      <node
        v-for="(x, i) in nodeData"
        :key="x.id"
        v-model:node="nodeData[i]"
        :index="i"
      />
    </ul>
  </div>
</template>

<script
  lang="ts"
  setup
  name="XTree"
>
const props = defineProps({
  data: {
    type: Array,
    default: () => [],
  },
  modelValue: {
    type: Object,
    default: () => ({}),
  },
})

const nodeData = computed(() => {
  const fn = (arr) => {
    const res = reactive([])
    arr.forEach((n) => {
      const o = { ...n, ...defCfg }
      if (n.children && n.children.length > 0) o.children = fn(n.children)
      nodeIndex[n.id] = o
      res.push(o)
    })
    return res
  }
  return fn(props.data)
})

const current = computed({
  get: () => props.modelValue,
  set: (v) => emit('update:modelValue', v),
})

const emit = defineEmits(['update:modelValue', 'nodeClick'])

const defCfg = { open: true }

const nodeIndex = reactive({})

const nodeClick = (node?) => {
  emit('nodeClick', node)
}

const getParent = () => {
  const parent = []
  const fn = (arr) => {
    arr.forEach((item) => {
      parent.push(item)
      if (item.id === current.value.id) throw parent
      if (item.children) fn(item.children)
      parent.pop()
    })
  }
  try {
    fn(props.data)
    return parent
  } catch (e) {
    return parent
  }
}

provide('current', current)
provide('nodeClick', nodeClick)
provide('getParent', getParent)
</script>

<style scoped></style>
